package main

import (
	"flag"
	"image"
	"image/draw"
	"log"
	"os"
	"runtime"
	"runtime/pprof"
	"strconv"
	"time"

	_ "image/png"

	"golang.org/x/mobile/app"
	"golang.org/x/mobile/event"
	"golang.org/x/mobile/geom"
	"golang.org/x/mobile/gl/glutil"

	"code.google.com/p/jnj/ttf"
)

// sprites
const (
	books = iota
	fire
	gopher
)

// gopher states
const (
	empty = iota
	loaded
)

var (
	font        *ttf.Font
	screenImage *glutil.Image

	sprites = make([]*Sprite, 3)
	mc      *Sprite
	dest    int
	score   int
)
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")

func getImage(name string) image.Image {
	path := "images/" + name + ".png"
	f, err := os.Open(path)
	if err != nil {
		log.Fatal(err)
	}
	defer f.Close()
	img, _, err := image.Decode(f)
	if err != nil {
		log.Fatal(err)
	}
	return img
}

func loadSprites() {
	w, h := screenImage.Bounds().Dx(), screenImage.Bounds().Dy()

	img := getImage("books")
	s := NewSprite([]image.Image{img})
	s.pos = image.Pt(10, h-10-s.height)
	sprites[books] = s

	img = getImage("fire")
	s = NewSprite([]image.Image{img})
	s.pos = image.Pt(w-10-s.width, h-10-s.height)
	sprites[fire] = s

	img = getImage("empty")
	img2 := getImage("loaded")
	s = NewSprite([]image.Image{img, img2})
	s.pos = image.Pt(w/2-s.width/2, h-10-s.height)
	sprites[gopher] = s
	mc = s
}

func setup() {
	screenImage = glutil.NewImage(int(geom.Width.Px()), int(geom.Height.Px()))
	loadSprites()
	dest = sprites[gopher].pos.X
}

func redraw() {
	if screenImage == nil {
		setup()
	}

	// game logic goes here
	mc.pos.X += (dest - mc.pos.X) / 10.0
	if dest < mc.pos.X {
		mc.flipped = true
	} else if dest > mc.pos.X {
		mc.flipped = false
	}
	if mc.pos.X <= sprites[books].pos.X+50 {
		mc.state = loaded
	} else if mc.pos.X >= sprites[fire].pos.X-50 && mc.state == loaded {
		mc.state = empty
		score++
	}

	// draw the sprites
	draw.Draw(screenImage.RGBA, screenImage.Bounds(), image.White, image.ZP, draw.Src)
	for _, s := range sprites {
		draw.Draw(screenImage.RGBA, screenImage.Bounds().Add(s.pos), s.Img(), image.ZP, draw.Over)
	}
	s := "Obsolete language manuals incinerated: " + strconv.Itoa(score)
	font.Draw(screenImage.RGBA, s, image.Pt(10, 10), screenImage.Bounds().Dx()-20)

	screenImage.Upload()
	screenImage.Draw(geom.Point{0, 0}, geom.Point{geom.Width, 0}, geom.Point{0, geom.Height}, screenImage.Bounds())

	//debug.DrawFPS()
}

func touch(t event.Touch) {
	dest = int(t.Loc.X.Px()) - mc.width/2
}

func main() {
	runtime.GOMAXPROCS(2) // seems to prevent garbage collection lags

	var err error
	font, err = ttf.NewFont("/Library/Fonts/Arial Bold.ttf")
	if err != nil {
		log.Fatal(err)
	}
	font.SetSize(14)

	flag.Parse()
	if *cpuprofile != "" {
		f, err := os.Create(*cpuprofile)
		if err != nil {
			log.Fatal(err)
		}
		pprof.StartCPUProfile(f)
		go func() {
			time.Sleep(2 * time.Second)
			pprof.StopCPUProfile()
			os.Exit(0)
		}()
	}

	app.Run(app.Callbacks{
		Draw:  redraw,
		Touch: touch,
	})
}
